﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Transactions;

namespace HomeFramework.Model
{
    public class TransactionScript : IDisposable
    {
        private readonly HomeFrameworkDB db = new HomeFrameworkDB();

        public Handler FindByName(string name, string version)
        {
            var risp = db.Handlers
                .Where(x => x.Name.Equals(name) && x.Enabled && (string.IsNullOrEmpty(version) || x.Version.Equals(version)))
                .OrderByDescending(x => x.Version)
                .FirstOrDefault();

            if (risp != null)
                return risp;
            else
                return db.Handlers
                    .Where(x => x.Name.Equals(name) && x.Enabled)
                    .FirstOrDefault();
        }

        public IEnumerable<Handler> GetHandlers()
        {
            return from h in db.Handlers
                   orderby h.Name, h.Version
                   select h;
        }

        public Handler AddHandler(Handler h)
        {
            db.Handlers.AddObject(h);
            try
            {
                db.SaveChanges();
                return h;
            }
            catch (Exception)
            {
                throw new Exception("Unable to add service!");
            }
        }

        public void RemoveHandlerByID(int ID)
        {
            using (var t = new TransactionScope())
            {
                var h = db.Handlers.Single(x => x.ID == ID);
                var refs = h.References.ToList();

                foreach (var r in refs)
                    db.References.DeleteObject(r);

                db.Handlers.DeleteObject(h);
                db.SaveChanges();

                t.Complete();
            }
        }

        public void ChangeActivation(int ID, bool enabled)
        {
            var h = db.Handlers.Single(x => x.ID == ID);
            h.Enabled = enabled;
            db.SaveChanges();
        }

        public Handler GetHandler(int ID)
        {
            return db.Handlers.SingleOrDefault(x => x.ID == ID);
        }

        public List<Reference> GetReferences(int ID)
        {
            return GetHandler(ID).References.ToList();
        }

        public void AddReference(Reference arg, int HandlerID)
        {
            try
            {
                var h = db.Handlers.Single(x => x.ID == HandlerID);
                h.References.Add(arg);
                db.References.AddObject(arg);
                db.SaveChanges();
            }
            catch (SqlException sx)
            {
                if (sx.Class == 14)
                    throw new Exception("Reference already added!");
                else
                    throw new Exception(sx.Message);
            }
            catch (Exception)
            {
                throw new Exception("Unable to add reference!");
            }
        }

        public void RemoveReference(int HandlerID, int ID)
        {
            var h = db.Handlers.Single(x => x.ID == HandlerID);
            var r = h.References.Single(x => x.ID == ID);
            h.References.Remove(r);
            db.References.DeleteObject(r);
            db.SaveChanges();
        }

        public void Dispose()
        {
            db.Dispose();
        }
    }
}